<!--
 * @Author         : ygl
 * @Date           : 2024-10-11 15:53
 * @LastEditTime   : 2025-09-05 16:33
 * @LastEditors    : Please set LastEditors
 * @Description    :
-->
<template>
  <div class="gante1">
    <div class="scroll-wrapper">
      <div class="left-wrapper">
        <div class="left-header">
          <div class="list-header">
            <div>{{ labelKey.label1 }}</div>
            <div>{{ labelKey.label2 }}</div>
          </div>
        </div>
        <div ref="listBody" @scroll="scrollSyncRight" class="left-body">
          <ProgressItem
						:style="{ color: positionItemIdnex === index ? '#70bdff' : '#fff' }"
						:labelKey="labelKey"
						@handlePositionItem="positionItem($event, index)"
						v-for="(item, index) in list"
						:key="item.aoNo"
						:model="item"
					/>
        </div>
      </div>

      <div class="right-wrapper">
        <div ref="ganteHeader" class="gante-header">
          <!-- 头部 -->
          <div class="date-column" v-for="item in tableHeaderData[timeRange]" :key="item.date">
            <div class="date">{{ item.date }}</div>
            <div class="time-column">
              <div class="time" v-for="obj in item.child" :key="obj">
                <div>{{ obj }}</div>
              </div>
            </div>
          </div>
        </div>

        <!-- 内容 -->
        <div ref="ganteBody" class="gante-body" @scroll="scrollSync">
          <TableItem :timeRange="timeRange" :model="item" v-for="item in list" :key="item.number" />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { nextTick, ref, watch } from 'vue'
import dayjs from 'dayjs'
import ProgressItem from './ProgressItem.vue'
import TableItem from './TableItem.vue'

const props = defineProps({
  list: {
    type: Array,
    required: true,
    default: () => []
  },
  labelKey: {
    type: Object,
    required: true,
    default: () => ({
      label1: '',
      label1Key: '',
      label2: '',
      label2Key: ''
    })
  },
  ganteTimeStr: {
    type: String,
    required: false,
    default: ''
  },
  propsDate: {
    type: Date,
    default: () => new Date(),
    require: false
  },
  propsDayDate: {
    type: String,
    default: () => '',
    require: false
  }
})

const ganteHeader = ref()
const ganteBody = ref()
const listBody = ref()
const positionItemIdnex = ref(-1)
function positionItem (item, index) {
  const style = item.deviceStates[0].style[timeRange.value]
  const value = style.match(/margin-left:(\d+\.?\d*)vw;/)[1]
  positionItemIdnex.value = index
  ganteBody.value.scrollLeft = value / 100 * window.innerWidth
}

// #region  列表滚动
// 甘特图内容同步滑动
function scrollSync () {
  ganteHeader.value.scrollLeft = ganteBody.value.scrollLeft
  listBody.value.scrollTop = ganteBody.value.scrollTop
}

// 左侧滑动
function scrollSyncRight () {
  ganteBody.value.scrollTop = listBody.value.scrollTop
}

// 甘特图头部同步滑动
const timeRange = ref(2) // 0:月 1:天 2:小时
nextTick().then(() => {
  ganteHeader.value.addEventListener('wheel', debounce(500))
})

let debounceTimer
function debounce (delay) {
  return function (event) {
    clearTimeout(debounceTimer) // 每次滚动时重置计时器
    debounceTimer = setTimeout(() => {
      if (event.deltaY > 0) {
        if (timeRange.value < 2) {
          timeRange.value++
        }
      } else {
        if (timeRange.value > 0) {
          timeRange.value--
        }
      }
      // console.log('鼠标滚动中，滚动方向：', event.deltaY > 0 ? '向下滚动' : '向上滚动')
    }, delay) // 只有在延迟时间内没有新事件时才会触发
  }
}
// #endregion

// 根据客户需求改
// let allWorkMonth = []

const tableData = ref([])

watch(
  () => props.list,
  val => {
    if (val && val.length > 0) {
      tableData.value = [].concat(...val)

      getBeginAndEndDate(tableData.value)
      getTableHeaderData()
      setTableColumnStyle(val)
    }
  }
)

// 获取开始时间和结束时间
let startTime = null
let filingTime = null
// function getBeginAndEndDate(data = []) {
//   startTime = null
//   filingTime = null
//   startTime = Math.min(...data.map(d => new Date(d.startTime)))
//   filingTime = Math.max(...data.map(d => new Date(d.filingTime)))
// }
function getBeginAndEndDate (data = []) {
  const timestamps = data.flatMap(d => [...(d.deviceStates?.flatMap(s => [s.startTime, s.filingTime]) || [])])
    .map(t => new Date(t))

  startTime = timestamps.length ? Math.min(...timestamps) : null
  filingTime = timestamps.length ? Math.max(...timestamps) : null
}

const tableHeaderData = ref([])
const allWorkTime = []
function getTableHeaderData () {
  const tableHeaderRange0 = []
  const tableHeaderRange1 = []
  const tableHeaderRange2 = []

  const startYear = new Date(startTime).getFullYear()
  const startMonth = (new Date(startTime).getMonth() + 1 + '').padStart(2, '0')

  const endYear = new Date(filingTime).getFullYear()
  const endMOnth = (new Date(filingTime).getMonth() + 1 + '').padStart(2, '0')

  const months = []
  const days = []
  const hours = []

  // 设置月
  for (let i = startYear; i <= endYear; i++) {
    const obj = {
      date: i,
      child: []
    }

    if (i === startYear) {
      for (let j = startMonth; j <= 12; j++) {
        months.push(`${i}/${(j + '').padStart(2, '0')}`)
        obj.child.push((j + '').padStart(2, '0'))
      }
    } else if (i === endYear) {
      for (let j = 1; j <= endMOnth; j++) {
        months.push(`${i}/${(j + '').padStart(2, '0')}`)
        obj.child.push((j + '').padStart(2, '0'))
      }
    } else {
      for (let j = 1; j <= 12; j++) {
        months.push(`${i}/${(j + '').padStart(2, '0')}`)
        obj.child.push((j + '').padStart(2, '0'))
      }
    }
    tableHeaderRange0.push(obj)
  }

  tableHeaderData.value[0] = tableHeaderRange0
  allWorkTime[0] = months

  // 设置日
  for (let j = 0; j < months.length; j++) {
    const obj = {
      date: months[j],
      child: []
    }
    const day = dayjs(months[j]).daysInMonth()

    if (dayjs(new Date(startTime)).format('YYYY/MM') === months[j]) {
      for (let i = dayjs(new Date(startTime)).format('DD'); i <= day; i++) {
        const str = (i + '').padStart(2, '0')
        obj.child.push(str)
        days.push(`${months[j]}/${str}`)
      }
    } else {
      for (let i = 1; i <= day; i++) {
        const str = (i + '').padStart(2, '0')
        obj.child.push(str)
        days.push(`${months[j]}/${str}`)
      }
    }
    tableHeaderRange1.push(obj)
  }

  tableHeaderData.value[1] = tableHeaderRange1
  allWorkTime[1] = days

  // 设置时
  for (let j = 0; j < days.length; j++) {
    const obj = {
      date: days[j],
      child: []
    }
    const hour = 24

    if (dayjs(new Date(startTime)).format('YYYY/MM/DD') === months[j]) {
      for (let i = dayjs(new Date(startTime)).format('HH') - 1; i < hour; i++) {
        const str = (i + '').padStart(2, '0')
        obj.child.push(str)
        hours.push(`${days[j]} ${str}`)
      }
    } else {
      for (let i = 0; i < hour; i++) {
        const str = (i + '').padStart(2, '0')
        obj.child.push(str)
        hours.push(`${days[j]} ${str}`)
      }
    }
    tableHeaderRange2.push(obj)
  }

  tableHeaderData.value[2] = tableHeaderRange2
  allWorkTime[2] = hours

  console.log('tableHeaderData', tableHeaderData.value)
  console.log('allWorkTime', allWorkTime)
}

function setTableColumnStyle (list) {
  const formats = ['YYYY/MM', 'YYYY/MM/DD', 'YYYY/MM/DD HH'] // 月、日、时
  list.forEach(item => {
    item.deviceStates.forEach((d) => {
      d.style = []
      for (let i = 0; i < formats.length; i++) {
        const { indexStart, indexEnd } = getIndexAndEnd(d, i, formats[i])

        const width = (indexEnd - indexStart) * 30 // 30 是每个网格的宽度
        const left = indexStart * 30
        // item.style[i] = `margin-left:${left}px;width:${width}px;`
        d.style[i] = `margin-left:${(left / 1920) * 100}vw;width:${(width / 1920) * 100}vw;`
      }
    })
  })
}

// function setTableColumnStyle (list) {
//   const formats = ['YYYY/MM', 'YYYY/MM/DD', 'YYYY/MM/DD HH']
//   list.forEach((item) => {
//     item.style = []
//     for (let i = 0; i < 3; i++) {
//       const indexObj = getIndexAndEnd(item, i, formats[i])
//       const { indexEnd, indexStart } = indexObj
//       const width = (indexEnd - indexStart) * 30
//       const left = indexStart * 30
//       item.style[i] = `margin-left:${left}px;width:${width}px;`
//     }
//   })
// }

function getIndexAndEnd (task, range, format) {
  const { startTime, filingTime } = task
  let indexStart = 0
  let indexEnd = 0

  indexStart = allWorkTime[range].indexOf(dayjs(new Date(startTime)).format(format))
  indexEnd = allWorkTime[range].indexOf(dayjs(new Date(filingTime)).format(format))
  if (format !== 'YYYY/MM/DD HH') {
    indexEnd += 1
  }
  return { indexStart, indexEnd }
}

// function scrollTableByTime(date) {
// 	const str = dayjs(date).format('YYYY-MM')
// 	const index = allWorkMonth.findIndex((i) => i === str)
// 	if (index > 0) {
// 		const scroll = index * 30
// 		ganteBody.value.scrollLeft = scroll
// 	}
// }

// watch(
// 	() => props.propsDate,
// 	(val) => {
// 		scrollTableByTime(val)
// 	}
// )

defineExpose({
  ganteBody
})
</script>

<style lang="less" scoped>
.gante1 {
  font-size: 12px;
  background-size: 100% 100%;
  height: 100%;
  width: 100%;
  display: flex;
  .scroll-wrapper {
    width: 100%;
    display: flex;
    overflow-x: hidden;
    overflow-y: hidden;
    position: relative;
    .left-wrapper {
      margin-left: 12px;
      .left-header {
        width: 100%;
        display: flex;
        align-items: flex-end;
        height: 56px;
        .list-header {
          display: flex;
          align-items: center;
          width: 300px;
          height: 30px;
          border-bottom: 1px solid rgba(218, 248, 255, 0.3);
          background-size: 100% 100%;
          div {
            color: rgba(255, 255, 255, 1);
            &:nth-child(1) {
              text-align: center;
              width: 74px;
            }
            &:nth-child(2) {
              width: 200px;
              margin-left: 8px;
              text-align: left;
            }
          }
        }
      }
      .left-body {
        overflow: auto;
        height: calc(100% - 65px);
        &::-webkit-scrollbar {
          width: 0px;
        }
      }
    }
    .right-wrapper {
      margin-left: 12px;
      width: calc(100% - 345px);
      .gante-header {
        overflow: hidden;
        top: 0;
        left: auto;
        display: flex;

        background-color: rgba(112, 189, 255, 0.2);

        &::-webkit-scrollbar {
          width: 0px;
          height: 0px;
        }
        .date-column {
          color: rgba(255, 255, 255, 0.7);
          &:nth-child(1) {
            border-left: 1px solid rgba(218, 248, 255, 0.3);
          }
          .date {
            text-align: center;
            box-sizing: border-box;
            border-top: 1px solid rgba(218, 248, 255, 0.3);
            border-bottom: 1px solid rgba(218, 248, 255, 0.3);
            border-right: 1px solid rgba(218, 248, 255, 0.3);
            background-size: 100% 100%;
            height: 26px;
            line-height: 26px;
            box-sizing: border-box;
          }

          .time-column {
            height: 30px;
            display: flex;
            justify-content: space-between;
            .time {
              box-sizing: border-box;
              flex-shrink: 0;
              border-right: 1px solid rgba(218, 248, 255, 0.3);
              border-bottom: 1px solid rgba(218, 248, 255, 0.3);
              width: 30px;
              display: flex;
              align-items: center;
              justify-content: center;
              flex-direction: column;
              .day {
                color: rgba(174, 202, 245, 1);
              }
            }
          }
        }
      }

      .gante-body {
        position: relative;
        overflow: auto;
        height: calc(100% - 55px);
        display: flex;
        flex-direction: column;

        &::-webkit-scrollbar {
          width: 10px;
          height: 10px;
        }
        &::-webkit-scrollbar-thumb {
          background: rgba(23, 125, 239, 0.7);
          border-radius: 5px;
        }
        &::-webkit-scrollbar-track {
          background: rgba(186, 207, 219, 0.15);
        }

        .table-column {
          position: relative;
          width: 100%;
        }
      }
    }
  }
}
</style>
